export default {
  // 回形数组
  getLoopArray(row: number = 5, column: number = 5, initNum: number = 1):any[][] {
    let x = 0,
      y = 0;
    let dir = 1; // 方向 1 2 3 4 代表 → ↓ ← ↑
    let tempArr = new Array(row).fill(new Array(column).fill(null));
    let arr = JSON.parse(JSON.stringify(tempArr));
    while (arr.flat().some(item => item === null)) {
      if (arr[y] && arr[y][x] === null) {
        arr[y][x] = initNum++;
      } else {
        dir++;
        dir = dir > 4 ? dir % 4 : dir;
        switch (dir) {
          case 1:
            y++;
            break;
          case 2:
            x--;
            break;
          case 3:
            y--;
            break;
          case 4:
            x++;
            break;
        }
      }
      switch (dir) {
        case 1:
          x++;
          break;
        case 2:
          y++;
          break;
        case 3:
          x--;
          break;
        case 4:
          y--;
          break;
      }
    }
    return arr;
  },
  // 十进制转二进制
  ten2two(num: number): string {
    var arr: number[] = [];
    while (num > 0) {
      let temp = num % 2;
      arr.unshift(temp);
      num = Math.floor(num / 2);
      console.log(`num`, num);
    }
    console.log(`arr`, arr);
    return arr.join("");
  },
  hex2rgb(str: string): string {
    var arr: any[] = [];
    if (/^#/.test(str)) {
      str = str.slice(1);
    }
    if (str.length === 3) {
      arr = [str[0], str[0], str[1], str[1], str[2], str[2]];
    } else if (str.length === 6) {
      arr = [...str];
    } else {
      return "颜色格式有错";
    }
    let changeObj = {
      a: 10,
      b: 11,
      c: 12,
      d: 13,
      e: 14,
      f: 15,
    };
    arr = arr.map((item) => {
      if (/[a-f]/i.test(item)) {
        item = changeObj[item];
      }
      return item;
    });
    return `rgba(${arr[0] * arr[1]},${arr[2] * arr[3]},${arr[4] * arr[5]})`;
  },
  obj2search(obj: object): string {
    var str: string = "";
    for (let key in obj) {
      str += "&" + key + "=" + obj[key];
    }
    return str.slice(1);
  },
  search2obj(str: string): object {
    var obj: object = {};
    str.split("&").forEach((item) => {
      var [key, value] = item.split("=");
      obj[key] = value;
    });
    return obj;
  },
  myCreate: function (obj: object): void {
    function F() {}
    F.prototype = obj;
    return new F();
  },
  myInstanceof: function (left: object, right: Function): boolean {
    const prototype = right.prototype;
    let proto = Object.getPrototypeOf(left);
    while (true) {
      if (!proto) return false;
      if (proto === prototype) return true;
      proto = Object.getPrototypeOf(proto);
    }
  },
  // new 构造函数
  objectFactory: function (F: Function, ...rest: any[]): object {
    let newObject = Object.create(F.prototype);
    let result = F.apply(newObject, rest);
    if (Object.prototype.toString.call(result) === "[object Function]") {
      return result;
    }
    return newObject;
  },
  // 防抖
  debounce: function (fun: Function, delay: number = 300) {
    var timer: any = null;
    return function (...arg: any[]) {
      let context: any = this;
      timer && clearTimeout(timer);
      timer = setTimeout(function () {
        fun.apply(context, arg);
        timer = null;
      }, delay);
    };
  },
  // 节流
  throttle: function (fun: Function, delay: number): Function {
    let timer: any = null;
    return function () {
      if (timer) return;
      var context = this,
        arg = arguments;
      timer = setTimeout(function () {
        fun.apply(context, arg);
        timer = null;
      }, delay);
    };
  },
  // 获取类型
  getType(target: any): string {
    var str: string = Object.prototype.toString.call(target);
    return str.split(" ")[1].slice(0, -1).toLowerCase();
  },
  myCall() {
    Function.prototype.myCall = function (context: any): void {
      if (typeof this !== "function") {
        console.error("type error");
      }
      let args = [...arguments].slice(1),
        result = null;
      context = context || window;
      context.fn = this;
      result = context.fn(...args);
      delete context.fn;
      return result;
    };
  },
  myApply() {
    Function.prototype.myApply = function (context: any): void {
      if (typeof this !== "function") {
        console.error("type error");
      }
      let args = arguments[1] || [],
        result = null;
      context = context || window;
      context.fn = this;
      result = context.fn(...args);
      delete context.fn;
      return result;
    };
  },
  myBind() {
    Function.prototype.myBind = function (context: any): Function {
      if (typeof this !== "function") {
        console.error("type error");
      }
      let args = arguments[1] || [],
        fn = this;
      return function Fn() {
        fn.apply(
          this instanceof Fn ? this : context,
          args.concat(...arguments)
        );
      };
    };
  },
  curry,
  deepCopy,
  dateFormat(dateInput: Date, format: string) {
    let year: number = dateInput.getFullYear();
    let month: number = dateInput.getMonth() + 1;
    let day: number = dateInput.getDate();
    format = format.replace(/yyyy/, year + "");
    format = format.replace(/MM/, month + "");
    format = format.replace(/dd/, day + "");
    return format;
  },
  exchangePlace(a: number, b: number): number[] {
    a = a + b;
    b = a - b;
    a = a - b;
    return [a, b];
  },
  // 数组随机排序
  randomArray(arr: any[]): any[] {
    var newArr: any[] = arr.slice(0);
    let length = newArr.length;
    while (length) {
      let randomIndex = Math.floor(Math.random() * length--);
      [newArr[length], newArr[randomIndex]] = [
        newArr[randomIndex],
        newArr[length],
      ];
    }
    return newArr;
  },
  getArraySum,
  // 数组扁平化 超级简单好用 比递归强太多了
  flatten(arr: any[]): any[] {
    return arr.toString().split(",");
  },
  jsonp(url: string) {
    let script = document.createElement("script");
    script.src = url;
    document.body.appendChild(script);
  },
  isObjEqual(obj1: object, obj2: object): boolean {
    var b = false;
    if (obj1 === obj2) {
      b = true;
    } else if (JSON.stringify(obj1) === JSON.stringify(obj2)) {
      b = true;
    } else {
      let key1Arr = Object.keys(obj1),
        key2Arr = Object.keys(obj2);
      if (key1Arr.sort().toString === key2Arr.sort().toString) {
        var isSame = key1Arr.some((key: any) => {
          return obj1[key] !== obj2[key];
        });
        isSame ? (b = false) : (b = true);
      } else {
        b = false;
      }
    }
    return b;
  },
};
// 函数科里化
function curry(fn: Function, ...args: any[]): Function {
  return fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);
}
// 深拷贝
function deepCopy<T>(obj: T): T {
  let newObj: any = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    newObj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key];
  }
  return newObj;
}
// 递归实现数组求和
function getArraySum(arr: number[], sum = 0): number {
  if (arr.length === 1) return (sum += arr[0]);
  return getArraySum(arr.slice(1), (sum += arr[0]));
}
// 实现斐波那契数列
function fibonacci(n: number): number {
  if (n == 0) return 0;
  if (n == 1) return 1;
  return fibonacci(n - 2) + fibonacci(n - 1);
}
